package org.example.classtopia.Service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.classtopia.Model.Entity.Curriculum;
import org.example.classtopia.Repository.CurriculumRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 学校数据抓取服务
 */
@Service
public class SchoolDataService {

    private final OkHttpClient httpClient;
    private final ObjectMapper objectMapper;
    
    @Autowired
    private CurriculumRepository curriculumRepository;

    public SchoolDataService() {
        this.httpClient = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .build();
        this.objectMapper = new ObjectMapper();
    }

    /**
     * 使用Cookie抓取学校数据
     */
    public boolean fetchDataWithCookie(String cookie) {
        try {
            // 0. 清洗Cookie字符串（去除换行符、回车符、首尾空格）
            cookie = cleanCookie(cookie);
            
            // 1. 验证Cookie是否有效
            if (!validateCookie(cookie)) {
                System.out.println("Cookie验证失败，可能已过期或无效");
                return false;
            }

            // 2. 抓取课表数据
            boolean scheduleSuccess = fetchCurriculumData(cookie);
            
            return scheduleSuccess;
            
        } catch (Exception e) {
            System.err.println("数据抓取过程中发生异常: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 验证Cookie是否有效
     */
    private boolean validateCookie(String cookie) {
        try {
            Request request = new Request.Builder()
                    .url("https://zhlj.whu.edu.cn/pc/index")
                    .addHeader("Cookie", cookie)
                    .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .build();

            try (Response response = httpClient.newCall(request).execute()) {
                return response.isSuccessful();
            }
        } catch (IOException e) {
            System.err.println("Cookie验证失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 抓取课表数据
     */
    private boolean fetchCurriculumData(String cookie) {
        try {
            Request request = new Request.Builder()
                    .url("https://zhlj.whu.edu.cn/whdxIndex/getCurriculum?date=")
                    .addHeader("Cookie", cookie)
                    .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .addHeader("Referer", "https://zhlj.whu.edu.cn/pc/index")
                    .build();

            try (Response response = httpClient.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    String jsonData = response.body().string();
                    System.out.println("获取到课表数据: " + jsonData);
                    
                    // 解析JSON数据
                    JsonNode rootNode = objectMapper.readTree(jsonData);
                    
                    if (rootNode.get("result").asInt() == 1) {
                        JsonNode dataArray = rootNode.get("data");
                        
                        // 清空用户原有课表数据（假设用户ID为1，实际应从当前登录用户获取）
                        Long userId = 1L; // TODO: 从当前登录用户获取
                        curriculumRepository.deleteByUserId(userId);
                        
                        // 解析每一天的课程
                        for (JsonNode dayNode : dataArray) {
                            int day = dayNode.get("day").asInt();
                            JsonNode curriculumList = dayNode.get("curriculumList");
                            
                            // 解析每一节课
                            for (JsonNode courseNode : curriculumList) {
                                Curriculum curriculum = new Curriculum();
                                curriculum.setUserId(userId);
                                curriculum.setDay(day);
                                
                                // 只保存有课的数据
                                if (courseNode.get("hasClass").asBoolean()) {
                                    curriculum.setTeacher(getStringValue(courseNode, "teacher"));
                                    curriculum.setCourseName(getStringValue(courseNode, "name"));
                                    curriculum.setFromClass(getIntValue(courseNode, "fromClass"));
                                    curriculum.setEndClass(getIntValue(courseNode, "endClass"));
                                    curriculum.setClassroom(getStringValue(courseNode, "classroom"));
                                    curriculum.setFromWeek(getIntValue(courseNode, "fromWeek"));
                                    curriculum.setEndWeek(getIntValue(courseNode, "endWeek"));
                                    curriculum.setClassCount(getIntValue(courseNode, "classCount"));
                                    curriculum.setHasClass(true);
                                    curriculum.setSectionPlan(getStringValue(courseNode, "sectionPlan"));
                                    curriculum.setCourseTypes(getStringValue(courseNode, "courseTypes"));
                                    
                                    // 保存到数据库
                                    curriculumRepository.save(curriculum);
                                    
                                    System.out.println("保存课程: " + curriculum.getCourseName() + 
                                                     ", 教师: " + curriculum.getTeacher() + 
                                                     ", 星期: " + day + 
                                                     ", 节次: " + curriculum.getFromClass() + "-" + curriculum.getEndClass());
                                }
                            }
                        }
                        
                        System.out.println("课表数据抓取并保存成功");
                        return true;
                    } else {
                        System.err.println("API返回失败，result: " + rootNode.get("result").asInt());
                        return false;
                    }
                } else {
                    System.err.println("HTTP请求失败，状态码: " + response.code());
                    return false;
                }
            }
        } catch (IOException e) {
            System.err.println("课表数据抓取失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 清洗Cookie字符串
     * 去除换行符、回车符、首尾空格等可能导致HTTP请求失败的字符
     */
    private String cleanCookie(String cookie) {
        if (cookie == null) {
            return null;
        }
        
        // 去除换行符(\n)、回车符(\r)、制表符(\t)和首尾空格
        String cleaned = cookie.replaceAll("[\r\n\t]", "").trim();
        
        System.out.println("原始Cookie长度: " + cookie.length() + ", 清洗后长度: " + cleaned.length());
        
        return cleaned;
    }

    /**
     * 安全获取字符串值
     */
    private String getStringValue(JsonNode node, String fieldName) {
        JsonNode fieldNode = node.get(fieldName);
        return (fieldNode != null && !fieldNode.isNull()) ? fieldNode.asText() : null;
    }

    /**
     * 安全获取整数值
     */
    private Integer getIntValue(JsonNode node, String fieldName) {
        JsonNode fieldNode = node.get(fieldName);
        return (fieldNode != null && !fieldNode.isNull()) ? fieldNode.asInt() : null;
    }

    /**
     * 直接从JSON字符串保存课表数据（支持Selenium等方式）
     * @param jsonData 课表JSON字符串
     * @param userId 用户ID
     * @return 是否保存成功
     */
    public boolean saveCurriculumFromJson(String jsonData, Long userId) {
        try {
            JsonNode rootNode = objectMapper.readTree(jsonData);
            if (rootNode.get("result").asInt() == 1) {
                JsonNode dataArray = rootNode.get("data");
                curriculumRepository.deleteByUserId(userId);
                for (JsonNode dayNode : dataArray) {
                    int day = dayNode.get("day").asInt();
                    JsonNode curriculumList = dayNode.get("curriculumList");
                    for (JsonNode courseNode : curriculumList) {
                        Curriculum curriculum = new Curriculum();
                        curriculum.setUserId(userId);
                        curriculum.setDay(day);
                        if (courseNode.get("hasClass").asBoolean()) {
                            curriculum.setTeacher(getStringValue(courseNode, "teacher"));
                            curriculum.setCourseName(getStringValue(courseNode, "name"));
                            curriculum.setFromClass(getIntValue(courseNode, "fromClass"));
                            curriculum.setEndClass(getIntValue(courseNode, "endClass"));
                            curriculum.setClassroom(getStringValue(courseNode, "classroom"));
                            curriculum.setFromWeek(getIntValue(courseNode, "fromWeek"));
                            curriculum.setEndWeek(getIntValue(courseNode, "endWeek"));
                            curriculum.setClassCount(getIntValue(courseNode, "classCount"));
                            curriculum.setHasClass(true);
                            curriculum.setSectionPlan(getStringValue(courseNode, "sectionPlan"));
                            curriculum.setCourseTypes(getStringValue(courseNode, "courseTypes"));
                            curriculumRepository.save(curriculum);
                        }
                    }
                }
                System.out.println("Selenium课表数据保存成功");
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 直接从JSON字符串保存课表数据（支持Selenium等方式）
     * @param jsonData 课表JSON字符串
     * @param userId 用户ID
     * @param shouldClearFirst 是否先清空用户数据（首次调用传true，后续传false）
     * @return 是否保存成功
     */
    public boolean saveCurriculumFromJson(String jsonData, Long userId, boolean shouldClearFirst) {
        try {
            JsonNode rootNode = objectMapper.readTree(jsonData);
            if (rootNode.get("result").asInt() == 1) {
                JsonNode dataArray = rootNode.get("data");
                
                // 只在首次调用时清空数据
                if (shouldClearFirst) {
                    curriculumRepository.deleteByUserId(userId);
                    System.out.println("清空用户 " + userId + " 的原有课程数据");
                }
                
                for (JsonNode dayNode : dataArray) {
                    int day = dayNode.get("day").asInt();
                    JsonNode curriculumList = dayNode.get("curriculumList");
                    for (JsonNode courseNode : curriculumList) {
                        Curriculum curriculum = new Curriculum();
                        curriculum.setUserId(userId);
                        curriculum.setDay(day);
                        if (courseNode.get("hasClass").asBoolean()) {
                            curriculum.setTeacher(getStringValue(courseNode, "teacher"));
                            curriculum.setCourseName(getStringValue(courseNode, "name"));
                            curriculum.setFromClass(getIntValue(courseNode, "fromClass"));
                            curriculum.setEndClass(getIntValue(courseNode, "endClass"));
                            curriculum.setClassroom(getStringValue(courseNode, "classroom"));
                            curriculum.setFromWeek(getIntValue(courseNode, "fromWeek"));
                            curriculum.setEndWeek(getIntValue(courseNode, "endWeek"));
                            curriculum.setClassCount(getIntValue(courseNode, "classCount"));
                            curriculum.setHasClass(true);
                            curriculum.setSectionPlan(getStringValue(courseNode, "sectionPlan"));
                            curriculum.setCourseTypes(getStringValue(courseNode, "courseTypes"));
                            curriculumRepository.save(curriculum);
                        }
                    }
                }
                System.out.println("Selenium课表数据保存成功");
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 根据用户ID、Cookie和起始日期，连续获取四周课表数据并保存
     * @param userId 用户ID
     * @param cookie Cookie字符串
     * @param date 起始日期（yyyy-MM-dd）
     * @return 是否全部成功
     */
    public boolean fetchCurriculumData(Long userId, String cookie, String date) {
        try {
            java.time.LocalDate startDate = java.time.LocalDate.parse(date);
            boolean allSuccess = true;
            for (int i = 0; i < 4; i++) {
                java.time.LocalDate targetDate = startDate.plusDays(i * 7);
                String dateStr = targetDate.toString();
                Request request = new Request.Builder()
                        .url("https://zhlj.whu.edu.cn/whdxIndex/getCurriculum?date=" + dateStr)
                        .addHeader("Cookie", cookie)
                        .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                        .addHeader("Referer", "https://zhlj.whu.edu.cn/pc/index")
                        .build();
                try (Response response = httpClient.newCall(request).execute()) {
                    if (response.isSuccessful()) {
                        String jsonData = response.body().string();
                        System.out.println("获取到课表数据(" + dateStr + "): " + jsonData);
                        boolean shouldClear = (i == 0); // 只在第一次清空
                        boolean saveSuccess = saveCurriculumFromJson(jsonData, userId, shouldClear);
                        if (!saveSuccess) {
                            allSuccess = false;
                            System.err.println("[" + dateStr + "]课表数据保存失败");
                        }
                    } else {
                        allSuccess = false;
                        System.err.println("[" + dateStr + "]HTTP请求失败，状态码: " + response.code());
                    }
                }
            }
            return allSuccess;
        } catch (Exception e) {
            System.err.println("课表数据抓取失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }
}
